在 Ruby 中,繼承不僅僅是共享方法;它更關注於 狀態的演進。當我們建立像 KaraokeSong < Song這樣的子類別時,我們建立了一種「是…的一種」關係,其中子類別繼承父類別的結構,同時也逐步完善自身的身份。
1. 初始化鏈
這個 super 關鍵字是世代之間的橋樑。在 initialize中呼叫 super 會將參數傳遞給父類別的建構函式,確保基礎的實例變數(@name、 @artist)在子類別加入其特定狀態(@lyrics)之前已被設定。
2. 方法擴展
覆蓋一個如 to_s 的方法,使我們能擴展行為。透過呼叫 super 於新定義內,我們取得父類別的字串輸出,並簡單地附加子類別的新資料,維持一條清晰的演進路徑。
main.py
TERMINALbash — 80x24
> Ready. Click "Run" to execute.
>
QUESTION 1
What is the primary function of the
super keyword in a subclass's initialize method?It clones the parent class into the child.
It passes arguments to the parent class's version of the method.
It deletes the instance variables of the parent.
It creates a global reference to the superclass.
✅ Correct!
Correct! super allows the parent class to handle the initialization of state it 'owns' before the child adds its own specific logic.❌ Incorrect
Recall that super is used to invoke the same-named method in the superclass.QUESTION 2
What happens to instance variables of a parent class during inheritance?
They are private and hidden from the subclass.
They are automatically populated even if 'super' is not called.
They become part of the subclass's state once the parent's initialize logic runs.
They are converted into class variables.
✅ Correct!
Instance variables are tied to the object; once initialized by the parent's code (via super), they exist within the subclass instance.❌ Incorrect
Instance variables aren't automatically populated; the initialization logic that sets them must be executed, usually via super.QUESTION 3
If you override
to_s in a subclass but do NOT call super, what happens?The parent's
to_s is still called automatically.The subclass implementation completely replaces the parent's implementation.
Ruby throws a SystemStackError.
The object defaults back to the standard
Object#to_s format.✅ Correct!
In Ruby, method overriding is total unless you explicitly use super to augment the parent's behavior.❌ Incorrect
Ruby does not automatically merge methods; it follows the lookup chain and stops at the first match.QUESTION 4
Which relationship best describes subclassing?
$Has-a$
$Is-a$
Contains-a
Provides-a
✅ Correct!
Inheritance defines an 'is-a' relationship (e.g., a KaraokeSong is a Song).❌ Incorrect
Composition is 'has-a'; inheritance is 'is-a'.QUESTION 5
What does the
inspect method reveal about an object's state?Only the public methods available.
The raw internal instance variables and their current values.
The source code of the class.
A list of all subclasses.
✅ Correct!
inspect is a debugging tool that shows the object's ID and all initialized instance variables.❌ Incorrect
inspect focuses on state (variables), not behavior (methods).State Evolution Analysis
Encapsulation vs. Tight Coupling
Consider a version of KaraokeSong where the developer implements to_s by directly interpolating the parent's variables: 'Song: #@name--#@artist (#@duration) [#@lyrics]'. Reading Context: We're correctly displaying the value of the @lyrics instance variable... The idea of a karaoke version of 'My Way' that lasts for 3,750 minutes is just too frightening to consider.
Q
So why is this a bad way to implement to_s? [Referencing the implementation of KaraokeSong#to_s that directly accesses parent instance variables]
Solution:
This is a bad implementation because it creates **tight coupling**. By directly accessing @name, @artist, and @duration (instance variables of the parent Song class), the subclass KaraokeSong becomes dependent on the internal implementation details of the parent. If the parent class changes its variable names (e.g., from @name to @title), the subclass breaks even though its own logic didn't change. It is better to use 'super' or call the parent's attribute methods to maintain **encapsulation** and ensure that changes in the parent class are automatically reflected in the subclass.
This is a bad implementation because it creates **tight coupling**. By directly accessing @name, @artist, and @duration (instance variables of the parent Song class), the subclass KaraokeSong becomes dependent on the internal implementation details of the parent. If the parent class changes its variable names (e.g., from @name to @title), the subclass breaks even though its own logic didn't change. It is better to use 'super' or call the parent's attribute methods to maintain **encapsulation** and ensure that changes in the parent class are automatically reflected in the subclass.
Q
How does using the 'super' keyword solve the issue described above?
Solution:
By using 'super' within the subclass's to_s method, you delegate the responsibility of formatting the basic song information back to the Song class. This ensures that if the Song class changes how it displays itself (e.g., changing the separator from '--' to ' by '), KaraokeSong automatically inherits that change without needing any manual code updates.
By using 'super' within the subclass's to_s method, you delegate the responsibility of formatting the basic song information back to the Song class. This ensures that if the Song class changes how it displays itself (e.g., changing the separator from '--' to ' by '), KaraokeSong automatically inherits that change without needing any manual code updates.